extends CharacterBody2D


class_name CharacterBody2D_Unit


signal event_finished(node: CharacterBody2D_Unit)


@onready var character_component: CharacterComponent = $CharacterComponent
@onready var gravity_element: GravityElement = $CharacterComponent/Move/MoveComponent/GravityElement
@onready var node_2d: Node2D = $Node2D


@export var is_enable: bool = true: set = __set_enable


func _ready() -> void:
    character_component.event_on_message.connect(on_message)
    character_component.event_on_effect.connect(on_effect)

func __set_enable(v: bool) -> void:
    is_enable = v
    visible = v
    process_mode = ProcessMode.PROCESS_MODE_INHERIT if v else ProcessMode.PROCESS_MODE_DISABLED

func get_character() -> CharacterComponent:
    return character_component

func on_message(character: CharacterComponent, e: CharacterEvent) -> void:
    match e.type:
        # 发射子弹时附带自身的子弹效果
        CharacterUnit.Event.ON_HIT_EXECUTE:
            e.meta.projectile.processor = character.processor.clone()
        # 远程武器击中目标
        CharacterUnit.Event.ON_HIT_SOMETHING:
            if e.meta.body is HurtBoxComponent:
                var hurtbox: HurtBoxComponent = e.meta.body
                # 命中的是自身的HurtBox
                if hurtbox.character == character:
                    e.cancel()
                    return
                # 击中目标
                var damage: Dictionary[String, int] = character.meta.pick()
                CharacterUnit.post(character, CharacterUnit.Event.ON_HIT_ENEMY, {
                    "enemy": hurtbox.character,
                    "direction": e.meta.direction,
                    "damage": damage,
                })
                # 触发伤害
                CharacterUnit.post(hurtbox.character, CharacterUnit.Event.ON_HIT_ATTACK, {
                    "enemy": character,
                    "direction": e.meta.direction,
                    "damage": damage,
                })
        # 计算伤害
        CharacterUnit.Event.ON_HIT_ATTACK:
            character.on_effect(CharacterUnit.Effect.DO_DAMAGE, e.clone())

func on_effect(character: CharacterComponent, type: CharacterUnit.Effect, e: CharacterEvent) -> void:
    match type:
        # 击退效果
        CharacterUnit.Effect.DO_KNACKBACK:
            gravity_element.velocity = e.meta.force * e.meta.direction
        # 计算伤害&显示浮动数字
        CharacterUnit.Effect.DO_DAMAGE:
            var hurt: Dictionary[String, int] = e.meta.damage
            var enemy: CharacterComponent = e.meta.get("enemy")
            var damage_value: int  = hurt.damage
            if hurt.crit_rate == 1:
                BehaviorHelper.display_float_text(node_2d, str(hurt.damage), Color.GOLD)
            else:
                BehaviorHelper.display_float_text(node_2d, str(hurt.damage), Color.WHITE)

            if damage_value > 0:
                var hp: RangeAttribute = character.meta.items.hp
                hp.decrease(damage_value)

                var hurt_meta: Dictionary[String, Variant] = {"damage": hurt, "enemy": character}
                # 通知攻击者自身受到伤害
                CharacterUnit.post(enemy, CharacterUnit.Event.ON_HIT_HURT, hurt_meta)
                if hp.is_done():
                    CharacterUnit.post(character, CharacterUnit.Event.ON_DIE, hurt_meta)
                    # 通知攻击者自身死亡
                    CharacterUnit.post(enemy, CharacterUnit.Event.ON_HIT_KILL, hurt_meta)
        # 显示浮动数字
        CharacterUnit.Effect.DO_HEALTH:
            var health: Dictionary[String, int] = e.meta.damage
            var damage_value: int  = health.damage
            BehaviorHelper.display_float_text(node_2d, str(damage_value), Color.LIME_GREEN)
            if health.damage > 0:
                character.meta.items.hp.increase(health.damage)
